# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from fastapi import UploadFile
from config import get_settings
from exception import AppException
from common.utils.urls import UrlUtil
from common.enums.attach import AttachEnum
from common.models.attach import AttachModel
from plugins.censor.driver import CensorDriver
from plugins.storage.driver import StorageDriver
from apps.api.schemas.index_schema import UploadResultVo


class UploadService:

    @classmethod
    async def files(cls, file_in: UploadFile, scene: str, folder: str, user_id: int):
        """
        上传文件。

        Args:
            file_in (UploadFile): 文件对象。
            scene (str): 存储场景: 如: [image,video,document,package,know]。
            folder (str): 存储目录: 如: [buckets,agents,applies,perusal]。
            user_id (int): 用户ID。

        Returns:
            UploadResultVo: 上传结果Vo。

        Author:
            zero

        Desc:
            Draws:
                生成图片: storage/applies/draws/albums/20250605/aa.png
                缩略图片: storage/applies/draws/thumbnail/20250605/aa.png
                参考图片: storage/applies/draws/reference/20250605/aa.png
            Video:
                参考图片: storage/applies/draws/video/20250605/aa.png
                生成视频: storage/applies/draws/video/20250605/aa.mp4
            Knows:
                附件管理: storage/agents/know/20250605/aa.png
                导入文件: storage/agents/know/20250605/aa.pdf
            Chats:
                对话附件: storage/agents/chat/20250605/aa.png
        """
        if (not folder.startswith("buckets")
                and not folder.startswith("agents")
                and not folder.startswith("applies")
                and not folder.startswith("perusal")):
            raise AppException("不被支持存储目录: " + folder)

        folder_dir = folder.strip("/")
        if folder_dir == "buckets":
            folder_dir = folder.strip("/") + "/" + scene

        # 上传文件
        result = await StorageDriver.upload(
            file_in=file_in,
            root=get_settings().UPLOAD.get("root") or "",
            stores=get_settings().UPLOAD.get("path") or "",
            folder=folder_dir
        )

        # 违规审查
        t = AttachEnum.get_type_by_ext(result.get("ext"))
        if t == "image" and result.get("size") < 4096:
            path = await UrlUtil.to_absolute_url(result.get("path"))
            review = CensorDriver.REVIEW_IMAGE
            censor = await CensorDriver.image(user_id=user_id, scene=review, path=path)
            if censor is not None:
                await StorageDriver.delete(result.get("path"))
                raise AppException(f"上传图片违规: {censor}")

        # 记录上传
        attach = await AttachModel.create(
            uid=user_id,
            cid=0,
            file_type=AttachEnum.get_code_by_msg(t),
            file_name=result.get("name"),
            file_path=result.get("path"),
            file_size=result.get("size"),
            file_ext=result.get("ext"),
            is_user=1,
            is_attach=0,
            create_time=int(time.time()),
            update_time=int(time.time())
        )

        # 返回结果
        return UploadResultVo(
            id=attach.id,
            name=attach.file_name,
            size=attach.file_size,
            ext=attach.file_ext,
            path=attach.file_path,
            url=await UrlUtil.to_absolute_url(attach.file_path)
        )

    @classmethod
    async def kb(cls, file_in: UploadFile, scene: str):
        """
        知识库文件上传

        Args:
            file_in (UploadFile): 文件对象。
            scene (str): 上传场景。

        Returns:
            UploadResultVo: 上传结果Vo。

        Author:
            zero
        """
        supported_extensions = {
            "raw": ["txt", "md", "pdf", "docx", "doc", "ppt", "pptx", "html", "xlsx"],
            "csv": ["csv", "xls", "xlsx"]
        }

        extensions = file_in.filename.split(".")[-1].lower()
        if extensions not in supported_extensions.get(scene, []):
            raise AppException("不被支持的文件扩展")

        max_size = 30 * 1024 * 1024  # 30MB in bytes
        if file_in.size > max_size:
            raise AppException("文件大小不能超过30MB")

        folder = "agents/know"
        result = await StorageDriver.upload(file_in, root="public", stores="storage", folder=folder, synchro=True)
        return UploadResultVo(
            id=0,
            name=result["name"],
            size=result["size"],
            ext=result["ext"],
            path=result["path"],
            url=await UrlUtil.to_absolute_url(result["path"])
        )
